import os
import core_analysis
import sys
import shutil
cwd = os.path.split(os.path.realpath(__file__))[0]
sys.path.append(os.path.join(cwd, "../config/"))
import config


class ProcessCores():
    def __init__(self):
        """
        initialize configuration and other helper classes
        """
        self.cfsize = core_analysis.CoreFileSize()
        self.config = config.Config()
        self.crash = core_analysis.Crash()
        self.config.parse()
        trunk = os.path.join(cwd, "../../")
        self.results_dir = os.path.join(trunk, "client/results")
        self.mutation_folder = os.path.abspath(os.path.join(trunk, self.config.config["mutation_folder"]))
        self.fuzz_prog_folder = os.path.abspath(os.path.join(trunk, self.config.config["fuzzing_prog_folder"]))        
   
    def process_cores(self):
        """
        process core files generated by fuzzing application
        """
        #get unique core files using filesize technique
        unique_cores = self.cfsize.get_unique_cores(self.fuzz_prog_folder)
        
        #process unique core files 
        for unique_core in unique_cores:
            shutil.copy(unique_core, self.config.results_dir)
            crash_file = self.crash.get_file_that_cause_crash(unique_core, self.mutation_folder)
            shutil.copy(crash_file, self.config.results_dir)
        
    def process_core_bts(self):
        #get unique client identification number
        dfuzz_id = self.config.get_dfuzz_id()
        #get unique core files using filesize technique
        unique_cores = self.cfsize.get_unique_cores(self.results_dir)
        
        #process unique core files 
        for unique_core in unique_cores:
            crash_file = self.crash.get_file_that_cause_crash(unique_core, self.mutation_folder)
            #get unique crash hash (ie. hash of backtraces from core files
            crash_hash = ""
            try:
                gdb = core_analysis.CoreGDB()
                gdb.start_gdb()
                gdb.set_program(self.config.config["fuzzed_program"])
                gdb.set_core_file(unique_core)
                backtrace = gdb.get_backtrace()
                crash_hash = gdb.get_unique_crash_hash(backtrace)
            except:
                print "GDB FAILED To Process Core Files"
            #output unique crash results file    
            results_file = os.path.splitext(crash_file)[0]
            results_file = os.path.split(results_file)[1]+".results"
            results_file = os.path.join(self.config.results_dir, results_file)
            r_fh = open(results_file, "w")
            copy_of_unique_core = os.path.join(self.config.results_dir, os.path.split(crash_file)[1])
            r_fh.write(dfuzz_id+"|"+crash_hash+"|"+ copy_of_unique_core)
            r_fh.close()        
                
if __name__ == "__main__":
    p = ProcessCores()
    p.process_cores()        
    p.process_core_bts()